/*
 *  Copright: 2008 Philipp Leitner, Distributed Systems Group,
 *            TU Wien, leitner@infosys.tuwien.ac.at
 *
 *  This file is part of DAIOS.
 *
 *  DAIOS is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as
 *  published by the Free Software Foundation.
 * 
 *  DAIOS is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with DAIOS.  If not, see
 *  <http://www.gnu.org/licenses/>.
 * 
 */

package at.ac.tuwien.infosys.dsg.daios.wsdl.impl;

import java.util.LinkedList;
import java.util.List;

import javax.xml.namespace.QName;

import org.apache.xmlbeans.SchemaType;

import at.ac.tuwien.infosys.dsg.daios.framework.structs.DaiosMessage;
import at.ac.tuwien.infosys.dsg.daios.util.Utility;
import at.ac.tuwien.infosys.dsg.daios.wsdl.interfaces.IWSDLType;

/**
 * A Daios WSDL Complex type. This is the prevalent kind of top-level
 * WSDL type in RPC style Web Services.
 * 
 * @author philipp
 *
 */
public class WSDLComplexType extends WSDLType {
	
	private QName typeName = null;
	private SchemaType type = null;
	private DaiosMessage structure = null;
	
	/**
	 * Construct a new WSDL Complex Type from a XMLBeans SchemaType object.
	 * 
	 * @param name The element name to associate with this type.
	 * @param type The XMLBeans SchemaType.
	 */
	public  WSDLComplexType(QName name, SchemaType type) {
		
		this.type = type;
		this.name = name;
		
		if(type.getPrimitiveType() == null)
			typeName = type.getName();
		else
			typeName = type.getPrimitiveType().getName();
		
		// we use this list to store the content model of
		// the type
		List<IWSDLType> tmpTypes = new
			LinkedList<IWSDLType>();
		
		// if we have a content model get the child sequence
		if(type.getContentModel() != null)
			constructChildSequence(type.getContentModel(), tmpTypes);
		
		// convert to array
		seqTypes = Utility.convert(tmpTypes);
		
	}

	/**
	 * Get the SchemaType as defined by XMLBeans that underlies this IWSDLType.
	 * 
	 * @return The XMLBeans SchemaType.
	 */
	public SchemaType getType() {
		return type;
	}
	
	/**
	 * Get the qualified name of the type.
	 * 
	 * @return The QName of this type.
	 */
	public QName getTypeName() {
		
		// this is a hack in case of decimal values
		if(typeName.getLocalPart().equals("decimal"))
			return new QName(getConcreteDecimalValue(type.getDecimalSize()));
		
		return typeName;
		
	}
	
	/**
	 * Get the <i>structure</i> of this type. The structure is
	 * the Daios Message with a structural distance of exactly 0.
	 * 
	 * @return The structure of this type.
	 */	
	public DaiosMessage getStructure() {
		
		// check if we have computed the structure before
		if(structure != null)
			return structure;
		
		// else calculate and return the structure of this
		// type
		DaiosMessage comp = new DaiosMessage();
		parseType(comp);
		return structure = comp;
		
	}

	/**
	 * Parse a SchemaType to create its structure. This is a wrapper around
	 * the parser method provided by the superclass implementation.
	 */	
	private void parseType(DaiosMessage m) {
		for(IWSDLType t: seqTypes) {
			parseType(t.getName().getLocalPart(), t.getType(), m, false);
		}	
	}
	
}
